<?php
/**
 *
 * @author ninetyseven.
 * @date 2023-03-27 22:53
 */

namespace App\Services;

use App\Enum\ActivityEnum;
use App\Enum\CommitteeMemberEnum;
use App\Enum\OrderEnum;
use App\Enum\TravelEnum;
use App\Enum\VolunteerEnum;
use App\Models\AbnormalModel;
use App\Models\ActivityApplicationModel;
use App\Models\ActivityModel;
use App\Models\CommunityModel;
use App\Models\ConfigModel;
use App\Models\DriverModel;
use App\Models\OrderModel;
use App\Models\UserCommunityModel;
use App\Models\VillagerUserModel;
use App\resources\Api\GetOrderListCollection;
use App\Services\Tools\HelpService;
use Darabonba\GatewaySpi\Models\InterceptorContext\request;
use Exception;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class VolunteerService extends BaseService
{
    /**
     * 添加志愿者
     * @param array $params
     * @return int
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-11 23:16
     */
    public static function volunteerAdd(array $params = []): int
    {
        $userId = $params['user_id'] ?? '';
        $avatar = $params['avatar'] ?? '';
        $realName = $params['real_name'] ?? '';
        $phone = $params['phone'] ?? '';
        $address = $params['address'] ?? '';

        if (empty($userId)) {
            throw new \Exception('用户id不能为空');
        }
        if (empty($avatar)) {
            throw new \Exception('照片不能为空');
        }
        if (empty($realName)) {
            throw new \Exception('姓名不能为空');
        }
        if (empty($phone)) {
            throw new \Exception('手机号不能为空');
        }
        if (empty($address)) {
            throw new \Exception('社区居住地不能为空');
        }

        $user = VillagerUserModel::query()->where('id', $userId)->first();
        if (!$user) {
            throw new \Exception('用户不存在');
        }
        $user->avatar = $avatar;
        $user->real_name = $realName;
        $user->phone = $phone;
        $user->residential_address = $address;
        if (!$user->save()) {
            throw new \Exception('用户信息更新错误');
        }

        //得到当前用户(村委/居委)所在的社区id
        $communityId = UserCommunityModel::query()->where('user_id', request()->userId)->where('user_type', self::getPlatformId())->value('community_id');
        if (!$communityId) {
            throw new \Exception('当前用户(村委/居委)未绑定社区');
        }

        //查询志愿者是否服务多个社区
        $communityCount = UserCommunityModel::query()
            ->where('user_type', TravelEnum::PLATFORM_VOLUNTEER)
            ->where('user_id', $userId)
            ->count();

        //为空,则添加志愿者身份
        if (empty($communityCount)) {
            $addData = [
                'user_id' => $userId,
                'user_type' => TravelEnum::PLATFORM_VOLUNTEER,
                'community_id' => $communityId,
            ];
            $res = UserCommunityModel::query()->create($addData);
            if (!$res) {
                throw new \Exception('添加志愿者身份失败');
            }
        }

        if ($communityCount > CommitteeMemberEnum::VILLAGER_COUNT) {
            throw new \Exception('志愿者最多服务5个社区');
        }

        return $communityCount;
    }

    /**
     * 社区服务列表
     * serviceList
     * @param int $userId
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/4/30
     */
    public static function serviceList(int $userId = 0): array
    {
        $community = UserCommunityModel::query()
            ->where('user_type', TravelEnum::PLATFORM_VOLUNTEER)
            ->where('user_id', $userId)
            ->get();
        if (!$community) {
            throw new Exception('志愿者未服务社区');
        }

        $communityIds = array_unique(array_column($community->toArray(), 'community_id'));

        $communityData = CommunityModel::query()->whereIn('id', $communityIds)->get();
        if (!$communityData) {
            throw new Exception('社区信息不存在');
        }

        $communityMemberId = UserCommunityModel::query()
            ->where('user_type', self::getPlatformId())
            ->where('user_id', request()->userId)
            ->value('community_id');
        if (!$communityMemberId) {
            throw new Exception('当前用户不存在社区');
        }
        $communityMemberData = CommunityModel::query()->where('id', $communityMemberId)->first();
        if (!$communityMemberData) {
            throw new Exception('不存在社区');
        }

        return [
            'community' => $communityData,
            'community_member' => $communityMemberData,
        ];
    }

    /**
     * 保存社区服务
     * serviceSave
     * @param array $params
     * @return bool
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/4/30
     */
    public static function serviceSave(array $params = []): bool
    {
        $communityId = $params['community_id'] ?? '';
        $userId = $params['user_id'] ?? '';
        $serviceType = $params['service_type'] ?? '';

        if (!$userId || !$communityId || !$serviceType) {
            throw new Exception('参数错误');
        }
        if ($serviceType == CommitteeMemberEnum::SERVICE_TYPE_NUM) {
            //仅服务该社区
            $res = UserCommunityModel::query()
                ->where('user_id', $userId)
                ->first();
            if ($res) {
                if (!$res->delete()) {
                    throw new Exception('保存失败');
                }
            }
        }

        $community = new UserCommunityModel();
        $community->user_id = $userId;
        $community->user_type = TravelEnum::PLATFORM_VOLUNTEER;
        $community->community_id = $communityId;
        $community->status = 1;
        $community->updated_at = time();
        $community->created_at = time();
        if (!$community->save()) {
            throw new Exception('保存失败');
        }

        return true;
    }

    public static function getSecurityOrderList()
    {
        $order = OrderModel::query()->where('is_warning', OrderEnum::ORDER_WARNING_YES)->where('volunteer_id', request()->userId)->select()->get();
        if (!$order) {
            throw new Exception('暂无预警订单');
        }

        $user = VillagerUserModel::query()->where([['id', '=', request()->userId]])->select('nick_name')->first();

        $driverId = array_unique(array_column($order->toArray(), 'driver_id'));
        $driver = DriverModel::query()->whereIn('id', $driverId)->select('id', 'driver_name', 'head_img', 'car_type', 'car_plate_number', 'cart_frame_no')->get();
        if (!$driver) {
            throw new \Exception('司机信息不存在');
        }

        $driver = array_column($driver->toArray(), null, 'id');
        foreach ($order as &$item) {
            $item['volunteer_name'] = $user['nick_name'];
            if (!empty($driver) && isset($driver[$item['driver_id']])) {
                $item['driver'] = $driver[$item['driver_id']];
            } else {
                $item['driver'] = $driver;
            }
        }

        return $order;
    }
    /**
     * 订单列表
     * @param int $type
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-15 16:36
     */
    public static function getOrderList(int $type = 0)
    {
        $platformId = self::getPlatformId();
        $where[] = ['is_accompany', '=', OrderEnum::ORDER_ACCOMPANY];

        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            //志愿者
            $where[] = ['volunteer_id', '=', request()->userId];
            $where[] = ['status', '!=', OrderEnum::STATUS_CANCEL];
            $where[] = ['activity_id', '=', 0];
            $where[] = ['go_order_id', '=', 0];


            $order = OrderModel::query()
                ->where($where)->orderBy('id', 'desc')
                ->paginate(HelpService::perPage())->toArray();

            return GetOrderListCollection::collection($order['data']);
        } else {
            throw new \Exception('志愿者接口，访问限制');
        }
    }

    /**
     * 订单列表,待报名的订单列表
     * @param int $type
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-15 16:36
     */
    public static function getWaitOrderList()
    {
        $platformId = self::getPlatformId();
        $where = [];
        $where[] = ['is_accompany', '=', OrderEnum::ORDER_ACCOMPANY];
        $where[] = ['go_order_id', '=', 0];
        $where[] = ['volunteer_id', '=', 0];

        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            $data = OrderModel::query()
                ->where('activity_id', '=', 0)
                ->where($where)->whereIn('status',[OrderEnum::STATUS_PENDING_ORDER,OrderEnum::STATUS_PENDING_TRAVEL])
                ->orderBy('id', 'desc')
                ->paginate(HelpService::perPage());
            if (!$data) {
                throw new \Exception('订单信息不存在');
            }

            return GetOrderListCollection::collection($data);
        } else {
            throw new \Exception('志愿者接口，访问限制。');
        }
    }

    /**
     * 志愿者 订单报名
     * @param $params
     * @return true
     * @throws Exception
     */
    public static function orderCancelApply($params=[])
    {
        $platformId = self::getPlatformId();
        $orderId = $params['order_id'];
        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            $orderInfo = OrderModel::query()->find($orderId);
            $model = OrderModel::query();
            // 找到返程订单
            if( $orderInfo['is_return'] == OrderEnum::ORDER_RETURN_CODE){
                $backOrderId = OrderModel::query()->where('go_order_id',$orderId)->value('id');
                if( empty($backOrderId) )
                {
                    throw new \Exception('访问异常，往返订单取消报名失败。');
                }
                $model =$model->whereIn('id', [$orderId,$backOrderId]);
            }else{
                $model =$model->where('id','=', $orderId);
            }

            $res = $model->update(['volunteer_id'=>0,'volunteer_status'=>VolunteerEnum::ACCOMPANY_TODO]);
            if (!$res) {
                throw new \Exception('订单信息不存在');
            }

            return true;
        } else {
            throw new \Exception('志愿者接口，访问限制。');
        }
    }
    /**
     * 志愿者 订单报名
     * @param $params
     * @return true
     * @throws Exception
     */
    public static function activityCancelApply($params=[])
    {
        $platformId = self::getPlatformId();
        $id = $params['id']; //活动ID
        $userId = request()->userId;
        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            // 删除 报名列表中的它
            $aaExists = ActivityApplicationModel::query()->where(['activity_id'=>$id,'user_id'=>$userId,'user_type'=>TravelEnum::PLATFORM_VOLUNTEER])->exists();
            if( empty($aaExists))
            {
                throw new \Exception('取消报名失败：本来无一物。');
            }
            ActivityApplicationModel::query()->where(['activity_id'=>$id,'user_id'=>$userId,'user_type'=>TravelEnum::PLATFORM_VOLUNTEER])->forceDelete();
            // 活动中 志愿者人数减1
            ActivityModel::query()->where(['id'=>$id])->decrement('apply_volunteer_num');
            return true;
        } else {
            throw new \Exception('志愿者接口，访问限制。');
        }
    }
    /**
     * 志愿者 订单报名
     * @param $params
     * @return true
     * @throws Exception
     */
    public static function orderApply($params=[])
    {
        $platformId = self::getPlatformId();
        $orderId = $params['order_id'];


        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            $orderInfo = OrderModel::query()->find($orderId);
            $model = OrderModel::query();
            // 找到返程订单
            if( $orderInfo['is_return'] == OrderEnum::ORDER_RETURN_CODE){
                $backOrderId = OrderModel::query()->where('go_order_id',$orderId)->value('id');
                if( empty($backOrderId) )
                {
                    throw new \Exception('访问异常，往返订单报名失败。');
                }
                $model =$model->whereIn('id', [$orderId,$backOrderId]);
            }else{
                $model =$model->where('id','=', $orderId);
            }

            $res = $model->update(['volunteer_id'=>request()->userId,'volunteer_status'=>VolunteerEnum::ACCOMPANY_TODO]);
            if (!$res) {
                throw new \Exception('订单信息不存在');
            }

            return true;
        } else {
            throw new \Exception('志愿者接口，访问限制。');
        }
    }
    public static function activityApply($params=[])
    {
        $platformId     = self::getPlatformId();
        $activityId     = $params['id'];
        $userId         = request()->userId;


        if ($platformId == TravelEnum::PLATFORM_VOLUNTEER) {
            $activityInfo = ActivityModel::query()->find($activityId);
            if (!$activityInfo) {
                throw new \Exception('活动不存在');
            }
            if( !($activityInfo['volunteer_num'] > $activityInfo['apply_volunteer_num']) )
            {
                throw new \Exception('报名失败：已经报名满员了。');
            }
            $aaExists = ActivityApplicationModel::query()->where(['activity_id'=>$activityId,'user_id'=>$userId,'user_type'=>TravelEnum::PLATFORM_VOLUNTEER])->exists();
            if( !empty($aaExists))
            {
                throw new \Exception('报名失败：您已经报过名了。');
            }

            // 报名人数+1
            ActivityModel::query()->where('id','=',$activityId)->increment('apply_volunteer_num');
            ActivityApplicationModel::query()->create([
                'activity_id'       => $activityId,
                'user_id'           => $userId,
                'application_no'    => HelpService::createRandNum(),
                'amount'            => 0,
                'user_type'         => TravelEnum::PLATFORM_VOLUNTEER,
                'community_id'      => $activityInfo['community_id'],
                'state'             => 1
            ]);
            return true;
        } else {
            throw new \Exception('志愿者接口，访问限制。');
        }
    }

    /**
     * 服务中订单详情
     * getOrderInfo
     * @param int $type
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/4/30
     */
    public static function getOrderInfo(int $type = 0)
    {
        $res = OrderModel::query()
            ->where('volunteer_status', $type)
            ->where('volunteer_id', request()->userId)
            ->first();
        if (!$res) {
            return [];
        }

        $res->start_time = date('m-d H:i', $res->start_time);

        return $res->toArray();
    }



    /**
     * // 可报名的活动列表
     * @param $applied:true已经报名，false可报名
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public static function getActivityList($applied=true)
    {
        $userId     = request()->userId;
        $userType   = TravelEnum::PLATFORM_VOLUNTEER;
        $communityId = UserCommunityModel::query()->where(['user_id'=>$userId,'user_type'=>$userType])->value('community_id');
        $model = ActivityModel::query()
            ->where('community_id', $communityId)
            //查询在活动时间内的活动
            ->where('start_time', '<=', date('Y-m-d'))
            ->where('end_time', '>=', date('Y-m-d'))
            ->where('state','=',ActivityEnum::STATUS_PASS)
            ->whereRaw('volunteer_num>apply_volunteer_num');
        if( $applied ) // 报名信息已存在
        {
            $model = $model->whereExists(function ($query) use ($userId,$communityId, $userType){
                $query->select(DB::raw(1))->from('activity_application')
                    ->where(['user_id'=>$userId, 'community_id'=>$communityId,'user_type'=>$userType])
                    ->whereRaw('sxcx_activity_application.activity_id = sxcx_activity.id');
            });
        }else{// 报名信息不存在
            $model = $model->whereNotExists(function ($query) use ($userId,$communityId, $userType){
                $query->select(DB::raw(1))->from('activity_application')
                    ->where(['user_id'=>$userId, 'community_id'=>$communityId,'user_type'=>$userType])
                    ->whereRaw('sxcx_activity_application.activity_id = sxcx_activity.id');
            });
        }
        return $model->select()->paginate(HelpService::perPage());
    }

    /**
     *
     * abnormalAdd
     * @param array $post
     * @return bool
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/7/6
     */
    public static function abnormalAdd(array $post): bool
    {
        $orderId = $post['order_id'] ?? 0;
        $userId = $post['user_id'] ?? 0;

        if(!$orderId || !$userId){
            throw new \Exception('参数错误');
        }

        $user = VillagerUserModel::query()->where('id', $userId)->first();
        if(!$user){
            throw new \Exception('用户信息不存在');
        }

        $order = OrderModel::query()->where('id', $orderId)->first();
        if(!$order){
            throw new \Exception('订单信息不存在');
        }

        $data = [
            'user_id' => $userId,
            'order_id' => $orderId,
            'username' => $user['real_name'],
            'phone' => $user['phone'],
            'reason' => $post['reason'] ?? '',
            'order_no' => $order['order_no'],
            'status' => 1,
        ];

        DB::beginTransaction();
        $res = AbnormalModel::query()->create($data);
        if(!$res){
            DB::rollBack();
            throw new \Exception('添加失败');
        }

        $order->volunteer_id = 0;
        if(!$order->save()){
            DB::rollBack();
            throw new \Exception('修改订单失败');
        }
        DB::commit();

        return true;
    }

    /**
     * 获取志愿者详情.
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-12 22:12
     */
    public function getVolunteerInfo(): array
    {
        $userId = \request()->userId;
        $res = VillagerUserModel::where('id', $userId)->first();

        $result = UserCommunityModel::query()
            ->where('user_id', $userId)
            ->where('user_type', TravelEnum::PLATFORM_VOLUNTEER)
            ->get();
        if (!empty($result)) {
            $communityIds = array_unique(array_column($result->toArray(), 'community_id'));
            $community = CommunityModel::query()->whereIn('id', $communityIds)->get();
            $communityAddress = array_column($community->toArray(), 'community_address');
            $res['community_address'] = implode(',', $communityAddress);
        }

        if (!$res) {
            throw new \Exception('用户信息不存在');
        }

        return $res->toArray();
    }
}
